﻿using System;
using System.Collections.Generic;
using System.Text;
using IFServerDLL;
using System.Threading;

namespace IFDemoServer
{
    public static class ClientCallbackQueue
    {
        /// <summary>
        /// 最大连接数
        /// </summary>
        const int _MAXCOUNT = 50;
        /// <summary>
        /// 无效的客户端连接
        /// </summary>
        private static Guid _FaulClientID = Guid.NewGuid();
        /// <summary>
        /// 客户端集合
        /// </summary>
        static volatile List<MyClientState> m_Callbacks = new List<MyClientState>();
        /// <summary>
        /// 静态类初始化
        /// </summary>
        static ClientCallbackQueue()
        {
            for (int i = 0; i < _MAXCOUNT; i++)
            {
                m_Callbacks.Add(new MyClientState());
            }
        }
        /// <summary>
        /// 添加到客户端集合队列
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        private static bool AddQueue(MyClientState state)
        {
            Console.WriteLine("新连接：" + state.ID.ToString());
            int index = -1;
            for (int i = 0; i < _MAXCOUNT; i++)
            {
                if (m_Callbacks[i].ID == _FaulClientID)
                {
                    index = i;
                    break;
                }
            }
            if (index >= 0)
            {
                DBAddClient(index, state);
                return true;
            }
            return false;
        }
        /// <summary>
        /// 新建一个连接
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        static public bool Add(MyClientState state)
        {
            int index = MyFindByID(state.ID);
            if (index < 0)
            {
                return AddQueue(state);
            }
            else
            {
                DBChangedClient(state.ID, state);
                return true;
            }
        }
        /// <summary>
        /// 保持连接
        /// </summary>
        /// <param name="id"></param>
        /// <param name="client"></param>
        static public void KeepAlive(Guid id, IResponeData client)
        {
            int index = MyFindByID(id);
            if (index < 0)
            {
                MyLog.WriteException(new Exception("出现未知的连接保持" + id.ToString()));
            }
            else
            {
                m_Callbacks[index].LastOnlineTime = DateTime.Now;
            }
        }
        /// <summary>
        /// 添加上线到数据库
        /// </summary>
        /// <param name="index"></param>
        /// <param name="state"></param>
        private static void DBAddClient(int index, ClientCallbackQueue.MyClientState state)
        {

            m_Callbacks[index] = state;
        }
        /// <summary>
        /// 根据客户端Guid获取集合索引
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private static int MyFindByID(Guid id)
        {
            int index = -1;
            for (int i = 0; i < _MAXCOUNT; i++)
            {
                if (m_Callbacks[i].ID == id)
                {
                    index = i;
                    break;
                }
            }
            return index;
        }
        /// <summary>
        /// 添加离线到数据库
        /// </summary>
        /// <param name="id"></param>
        public static void DBRemoveClient(Guid id)
        {
            int index = MyFindByID(id);
            if (index >= 0)
            {
                m_Callbacks[index].ID = _FaulClientID; ;
            }


        }
        /// <summary>
        /// 添加更新到数据库
        /// </summary>
        /// <param name="id"></param>
        /// <param name="state"></param>
        private static void DBChangedClient(Guid id, MyClientState state)
        {
            int index = MyFindByID(id);
            if (index >= 0)
            {
                m_Callbacks[index] = state;
            }


        }
        static public void DoMothed(Guid id, string methodName, object methodParam)
        {
            MyClientState client = null;
            for (int i = 0; i < _MAXCOUNT; i++)
            {
                if (m_Callbacks[i].ID == id)
                {
                    client = m_Callbacks[i];
                }
            }
            if (client == null)
                return;
            try
            {
                Thread t = new Thread(p =>
                    {
                        try
                        {
                            System.Reflection.MethodInfo info = typeof(IResponeData).GetMethod(methodName);
                            info.Invoke(client.Client, new object[] { p });
                            client.LastOnlineTime = DateTime.Now;
                        }
                        catch
                        {

                        }
                    });
                t.IsBackground = true;
                t.Start(methodParam);
            }
            catch
            {
                //MyLog.WriteException(ex);
                DBRemoveClient(client.ID);

            }




        }

        public class MyClientState
        {
            public MyClientState()
            {

                ID = _FaulClientID;

            }
            public const int FAILNUM = 1;
            public MyClientState(Guid id, IResponeData client)
            {
                ID = id;
                LastOnlineTime = DateTime.Now;

                Client = client;

            }

            public Guid ID { get; set; }
            public DateTime LastOnlineTime { get; set; }

            //public bool IsOnline { get; set; }
            public IResponeData Client { get; set; }
        }
    }
}
